﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using PaperRenderingInterfaces;
using DeepZoomPivotConstructor.PivotLib;
using HtmlAgilityPack;
using PaperPluginUtilities;
using DeepZoomPivotConstructor.ErrorAndLoggingInterfaces;

namespace TwikiLinkScanners
{
    /// <summary>
    /// Parse the main sequence page
    /// </summary>
    [Export(typeof(IPaperRender))]
    [PaperRender("MainATLASTwikiPulicPage")]
    public class ATLASMainPhysicsResults : IPaperRender
    {
#pragma warning disable 0649
        [Import]
        IWebAccess WebGetter;
#pragma warning restore 0649

#pragma warning disable 0649
        [Import]
        IPaperRenderEngine MyRender;
#pragma warning restore 0649

        public IEnumerable<PivotImage> Render(string renderAddress)
        {
            ///
            /// Get the document
            /// 

            Uri baseUri = new Uri(renderAddress);
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(WebGetter.GetUriAsString(baseUri));

            ///
            /// The layout is currently (I hope) fairly uniform.
            /// 

            var allTables = new EnumerableWrapper<HtmlNode>(doc.DocumentNode.SelectNodes("//table"));

            return allTables.SelectMany(tab => ParseTable(tab, baseUri));
        }

        /// <summary>
        /// Parse a table
        /// </summary>
        /// <param name="tab"></param>
        /// <param name="baseUri"></param>
        /// <returns></returns>
        private IEnumerable<PivotImage> ParseTable(HtmlNode tab, Uri baseUri)
        {
            var allRows = tab.ScanSubNodes("tr");
            return allRows.SelectMany(row => ParseSingleRow(row, baseUri));
        }

        private Dictionary<string, string> groupNameMapping = new Dictionary<string, string>()
        {
            {"Standard Model", "Standard Model"},
            {"B Physics", "B Physics"},
            {"Top Physics", "Top"},
            {"Higgs", "Higgs"},
            {"SUSY", "Exotics"},
            {"Exotics", "Exotics"},
            {"Monte Carlo", "Monte Carlo"},
            {"e/gamma", "EM ID"},
            {"Muon combined", "Muon ID"},
            {"Tau", "Tau ID"},
            {"Jet/EtMiss", "Jet/Missing ET ID"},
            {"Tracking", "Track ID"},
            {"Flavor Tagging", "B-Tagging"},
            {"Pixel tracker", "Tracking Detectors"},
            {"Semiconducter Tracker (SCT)", "Tracking Detectors"},
            {"Transition Radiation Tracker (TRT)", "Tracking Detectors"},
            {"Inner Detector (ID) combined (incl. ID alignment, tracking, and BCM)", "Tracking Detectors"},
            {"Liquid-Argon Calorimeter", "Calorimeters"},
            {"Tile Calorimeter", "Calorimeters"},
            {"Muon Spectrometer", "Muon Detectors"},
            {"Forward Detectors", "Forward Detectors"},
            {"Trigger (Including Level-1)", "Trigger/DAQ"},
            {"Data Acquisition and HLT system", "Trigger/DAQ"},
            {"Overall ATLAS", "Full Detector"},
            {"Detector Control System (DCS) and Safety", "Full Detector"},
            {"Luminosity, Data taking statistics and Data quality", "Full Detector"},
            {"Event Displays", "Event Displays"},
            {"Heavy Ions", "Heavy Ion"}
        };

#pragma warning disable 0649
        [Import]
        IErrorLogger MyLogger;
#pragma warning restore 0649

        /// <summary>
        /// Parse a single row of the table.
        /// </summary>
        /// <param name="row"></param>
        /// <param name="baseUri"></param>
        /// <returns></returns>
        private IEnumerable<PivotImage> ParseSingleRow(HtmlNode row, Uri baseUri)
        {
            ///
            /// There should be three columns
            /// 

            var allCols = row.ScanSubNodes("td").ToArray();
            if (allCols.Length != 3)
            {
                return Enumerable.Empty<PivotImage>();
            }

            ///
            /// The group name should be in the first row
            /// 

            string groupName = allCols[0].InnerText.CleanHTMLText();
            if (!groupNameMapping.ContainsKey(groupName))
            {
                if (MyLogger != null)
                {
                    MyLogger.LogMessage("ATLASMainPhysicsResults", "Found unknown group name '" + groupName + "' - skipping!");
                }
                return Enumerable.Empty<PivotImage>();
            }
            string pivotGroupname = groupNameMapping[groupName];

            ///
            /// Now, run the links we are looking at with this group name.
            /// 

            var allLinks = allCols[1].ScanSubNodes("a");
            var urisToScan = from l in allLinks
                             where l.Attributes["href"] != null
                             let u = new Uri(baseUri, l.Attributes["href"].Value)
                             where TwikiParseHelpers.isATLASTwikiLink(u)
                             let tword = TwikiParseHelpers.ExtractATLASTwikiWord(u)
                             where TwikiParseHelpers.IsSingleTwikiWord(tword)
                             select u;
            var urisToScanDone = urisToScan.ToArray();

            ///
            /// And parse for links and sub-page links.
            /// 

            var plots = urisToScanDone.SelectMany(u => MyRender.Render("HTMLSimpleTables", u.OriginalString));
            var secondPages = urisToScanDone.SelectMany(u => MyRender.Render("TwikSubLinkScanner", "/ScannerType=HTMLSimpleTables/" + u.OriginalString));
            var confNotes = urisToScanDone.SelectMany(u => MyRender.Render("ATLASMasterConfNotePage", u.OriginalString));

            var allpages = plots.Concat(secondPages).Concat(confNotes).Apply(pi => pi.Add("Group", pivotGroupname));

            return allpages;
        }
    }
}
